import { createStore, Commit } from 'vuex'
import axios from "axios";

export interface ResponseType<P = {}> {
  code: number;
  msg: string;
  data: P;
}

export interface UserProps {
  isLogin: boolean;
  nickName?: string;
  _id?: string;
  column?: string;
  email?: string;
}

export interface ImageProps {
  _id?: string;
  url?: string;
  createdAt?: string;
}

export interface ColumnProps {
  _id: string;
  title: string;
  avatar?: ImageProps;
  description: string;
}

export interface PostProps {
  _id?: string;
  title: string;
  content?: string;
  image?: ImageProps | string;
  createdAt?: string;
  column: string;
  excerpt?: string;
  author?: string;
}

export interface GlobalErrorProps {
  status: Boolean;
  message?: string;
}

export interface GlobalDataProps {
  token: String;
  loading: Boolean;
  columns: ColumnProps[];
  posts: PostProps[];
  user: UserProps;
  error: GlobalErrorProps;
}
const postAndCommit = async (url: string, mutationName: string, commit: Commit, payload: any) => {
  // debugger
  const { data } = await axios.post(url, payload)
  commit(mutationName, data)
  // debugger
  return data
}

const store = createStore<GlobalDataProps>({
  state: {
    token: localStorage.getItem('token') || '',
    loading: false,
    columns: [],
    posts: [],
    user: { isLogin: false },
    error: { status: false }
  },
  mutations: {
    // 测试用的login
    // login(state) {
    //   state.user = { ...state.user, isLogin: true, name: 'viking' }
    // },
    createPost(state, newPost) {
      state.posts.push(newPost)
    },
    fetchColumns(state, rawData) {
      state.columns = rawData.data.list
    },
    fetchColumn (state, rawData) {
      state.columns = [rawData.data]
    },
    fetchPosts (state, rawData) {
      state.posts = rawData.data.list
    },
    setLoading (state, status) {
      state.loading = status
    },
    setError (state, e: GlobalErrorProps) {
      state.error = e
    },
    login (state, rawData) {
      const { token } = rawData.data
      state.token = token
      localStorage.setItem('token', token)
      axios.defaults.headers.common.Authorization = `Bearer ${token}`
    },
    // 退出登录
    logout (state) {
      state.token = ''
      state.user = { isLogin: false }
      localStorage.removeItem('token')
      delete axios.defaults.headers.common.Authorization
    },
    fetchCurrentUser (state, rawData) {
      state.user = { isLogin: true, ...rawData.data }
    }
  },
  actions: {
    async fetchColumns ({ commit }) {
      // 使用async和await改造异步请求
      const { data } = await axios.get('/columns')
      commit('fetchColumns', data)
      return data
      // axios.get('/columns').then(res => {
      //   context.commit('fetchColumns', res.data)
      // }) 
    },
    async fetchColumn ({ commit }, columnId) {
      const { data } = await axios.get(`/columns/${columnId}`)
      commit('fetchColumn', data)
      return data
    },
    async fetchPosts ({ commit }, columnId) {
      const { data } = await axios.get(`/columns/${columnId}/posts`)
      commit('fetchPosts', data)
      return data
    },
    login ({ commit }, payload) {
      // debugger
      const data = postAndCommit('/user/login', 'login', commit, payload)
      return data
    },
    async fetchCurrentUser ({ commit }) {
      const { data } = await axios.get('/user/current')
      commit('fetchCurrentUser', data)
      return data
    },
    loginAndFetch ({ dispatch }, loginData) {
      return dispatch('login', loginData).then(() => {
        return dispatch('fetchCurrentUser')
      })
    },
    createPost ({ commit }, payload) {
      return postAndCommit('/posts', 'createPost', commit, payload)
    }
  },
  getters: {
    getColumnById: (state) => (id: string) => {
      return state.columns.find(c => c._id === id)
    },
    getPostsByCid: (state) => (cid: string) => {
      return state.posts.filter(post => post.column === cid)
    }
  }
})

export default store
